#include"../inc/SocketIO.h"
#include<iostream>
#include<string.h>

#include<unistd.h>
#include<sys/socket.h>

namespace http_server 
{
int socketIO::read_line(char* buf, int len)
{
	int i, ret;
	char c = '\0';
	for(i = 0; i < len-1; )
	{
		ret = recv(_fd, &c, 1, 0);
		if(-1 == ret)
		{
			if(errno == EINTR)
				continue;
			return EXIT_FAILURE;
		}
		else if(0 == ret) 
		{
			c = '\n';
			break;
		}
		else 
		{
			if(c == '\r')
				ret = Peek(&c);
			buf[i] = c;
			i++;
		}
	}
	buf[i] = '\0';
	return i;
}

int socketIO::Peek(char* buf)
{
	int ret = recv(_fd, buf, 1, MSG_PEEK);
	if(ret > 0 && *buf == '\n')
		recv(_fd, &buf, 1, 0);
	else 
		*buf = '\n';
	return ret;
}

int socketIO::hexit(char c)
{
	if(c >= '0' && c <= '9')
		return c - '0';
	if(c >= 'a' && c <= 'z')
		return c - 'a';
	if(c >= 'A' && c <= 'Z')
		return c - 'Z';
	
	return 0;
}

void socketIO::decode(char* to, const char* from)
{
	for( ; *from != '\0'; ++to, ++from)
	{
		if(from[0] == '%' && isxdigit(from[1]) && isxdigit(from[2]))
		{
			*to = hexit(from[1])*16 + hexit(from[2]);
			from += 2;
		}
		else 
			*to = *from;	
	}
	*to = '\0';
}

void socketIO::encode(char* to, int tosize, const char* from)
{
	int tolen;

	for(tolen = 0; *from != '\0' && tolen + 4 < tosize; ++from)
	{
		if(isalnum(*from) || strchr("/_.-~", *from) != (char*)0)
		{
			*to = *from;
			++to;
			++tolen;
		}
		else
		{
			sprintf(to, "%%%02x", (int)*from & 0xff);
			to += 3;
			tolen += 3;
		}
	}
	*to = '\0';
}

}
